package com.hdaccp.hbase;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

public class HBaseMusic {
    //读取hbase-site.xml配置文件
	static Configuration cfg = HBaseConfiguration.create();

	// 列出数据库中所有表
	public static void list() throws IOException {
		// 创建数据库链接
		Connection conn = ConnectionFactory.createConnection(cfg);
		// Admin用于管理HBase数据库的表信息
		Admin admin = conn.getAdmin();
		System.out.println("===list tables:===");
		for (TableName tn : admin.listTableNames())
			System.out.println(tn);
		conn.close();// 关闭连接
	}

	// 创建表
	public static void create(String tableName, String... familyNames)
			throws IOException {
	    //得到hbase的配置
		Connection conn = ConnectionFactory.createConnection(cfg);
		//管理表的对象
		Admin admin = conn.getAdmin();
		// TableName:以POJO对象来封装表的名字
		TableName tn = TableName.valueOf(tableName);
		if (admin.tableExists(tn)) { // 如果存在先删除
			admin.disableTable(tn);// 先使表无效
			admin.deleteTable(tn);
		}
		// HTableDescriptor包含了表的名字及其对应的列族
		HTableDescriptor htd = new HTableDescriptor(tn);
		for (String family : familyNames)
			htd.addFamily(new HColumnDescriptor(family));
		//创建表
		admin.createTable(htd);
		//关闭连接
		conn.close();
		System.out.println("create success!");
	}

	// 修改表-增加列族
	public static void addColumnFamily(String tableName, String... familyNames)
			throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Admin admin = conn.getAdmin();
		TableName tn = TableName.valueOf(tableName);
		HTableDescriptor htd = admin.getTableDescriptor(tn);
		for (String family : familyNames)
			htd.addFamily(new HColumnDescriptor(family));
		admin.modifyTable(tn, htd);
		conn.close();
		System.out.println("modify success!");
	}

	// 修改表-删减列族
	public static void removeColumnFamily(String tableName,
			String... familyNames) throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Admin admin = conn.getAdmin();
		TableName tn = TableName.valueOf(tableName);
		HTableDescriptor htd = admin.getTableDescriptor(tn);
		for (String family : familyNames)
			htd.removeFamily(Bytes.toBytes(family));// 删减指定列族
		admin.modifyTable(tn, htd);
		conn.close();
		System.out.println("remove success!");
	}

	// 查看表结构
	public static void describe(String tableName) throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Admin admin = conn.getAdmin();
		TableName tn = TableName.valueOf(tableName);
		HTableDescriptor htd = admin.getTableDescriptor(tn);
		System.out.println("===decribe " + tableName + ":===");
		for (HColumnDescriptor hcd : htd.getColumnFamilies()) {
			System.out.println(hcd.getNameAsString());
		}
		System.out.println("===============");
		conn.close();
	}

	static void put() throws IOException {
	    //得到数据库连接
		Connection conn = ConnectionFactory.createConnection(cfg);
		//得到表
		Table tb = conn.getTable(TableName.valueOf("music"));
		//写数据
		Put p = new Put(Bytes.toBytes("1_song1_2016-1-11"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("gender"),
				Bytes.toBytes("man"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"),
				Bytes.toBytes("song1"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("ryghme"),
				Bytes.toBytes("slow"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("singer"),
				Bytes.toBytes("singer1"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("terminal"),
				Bytes.toBytes("pc"));
		tb.put(p);
		p = new Put(Bytes.toBytes("2_song1_2016-1-11"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("gender"),
				Bytes.toBytes("woman"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"),
				Bytes.toBytes("song2"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("ryghme"),
				Bytes.toBytes("quick"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("singer"),
				Bytes.toBytes("singer2"));
		p.addColumn(Bytes.toBytes("info"), Bytes.toBytes("terminal"),
				Bytes.toBytes("android"));
		tb.put(p);
		conn.close();
	}

	/**
	 * 按行键获取
	 */
	static void get(String tableName, String rowKey) throws IOException {
	    //得到数据库连接
		Connection conn = ConnectionFactory.createConnection(cfg);
		//得到表的对象
		Table tb = conn.getTable(TableName.valueOf(tableName));
		//
		Get g = new Get(Bytes.toBytes(rowKey));
		//Resultset
		Result result = tb.get(g);
		System.out.println(String.format(
				"result.value=%s",
				Bytes.toString(result.value())));
		conn.close();
	}

	/**
	 * 按行键，列族获取
	 */
	static void get(String tableName, String rowKey, String family)
			throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Table tb = conn.getTable(TableName.valueOf(tableName));
		Get g = new Get(Bytes.toBytes(rowKey));
		g.addFamily(Bytes.toBytes(family));
		Result result = tb.get(g);
		System.out.println(String.format(
				"result.value=%s,result.toString():%s",
				Bytes.toString(result.value()), result));
		conn.close();
	}

	/**
	 * 按行键，列族，列修饰符获取
	 */
	static void get(String tableName, String rowKey, String family,
			String qualifier) throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Table tb = conn.getTable(TableName.valueOf(tableName));
		Get g = new Get(Bytes.toBytes(rowKey));
		g.addColumn(Bytes.toBytes(family), Bytes.toBytes(qualifier));
		Result result = tb.get(g);
		System.out.println(String.format(
				"result.value=%s",
				Bytes.toString(result.value())));
		conn.close();
	}

	static void scan(String tableName) throws IOException {
		Connection conn = ConnectionFactory.createConnection(cfg);
		Table tb = conn.getTable(TableName.valueOf(tableName));
		ResultScanner scanner = tb.getScanner(new Scan());// 全表扫描
		for (Result row : scanner) {
			System.out.println(row);
			for (Cell cell : row.listCells()) {
				System.out
						.println("Rowkey:" + Bytes.toString(row.getRow())
								+ "	Familiy:"
								+ Bytes.toString(CellUtil.cloneFamily(cell))
								+ "	Quilifier:"
								+ Bytes.toString(CellUtil.cloneQualifier(cell))
								+ "	Value:"
								+ Bytes.toString(CellUtil.cloneValue(cell)));
			}
		}
		conn.close();
	}

	public static void main(String[] args) throws IOException {
		//create("music", "info");// 创建表并指定1个列族 describe("music");
		//addColumnFamily("music", "f1", "f2");// 新增2个列族 describe("music");
		//removeColumnFamily("music", "f1", "f2");// 删除2个列族 describe("music");
		//list();
		//put();
		//get("music", "1_song1_2016-1-11");
		//get("music", "1_song1_2016-1-11", "info");
		//get("music", "1_song1_2016-1-11", "info", "name");
		//scan("music");*/

	}
}
